package com.aizhixin.lab.docker.service;

import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.docker.domain.*;
import com.aizhixin.lab.docker.entity.ContainerToImages;
import com.aizhixin.lab.docker.entity.LastOperation;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Transactional
public class AutoSaveImage implements Runnable {
    private DockerContainerService dockerContainerService;
    private ContainerToImagesService containerToImagesService;
    private ContainerDomain containerDomain;
    private AccountDTO accountDTO;
    private String token;
    private LastOperationService lastOperationService;
    private Long expire;
    private String token1;
    private RedisTemplate<String,String> redisTemplate;

    public AutoSaveImage(DockerContainerService dockerContainerService, ContainerToImagesService containerToImagesRepository, ContainerDomain containerDomainV2, AccountDTO accountDTO, String token, LastOperationService lastOperationRepository, Long expire,String token1,RedisTemplate<String,String> redisTemplate) {
        this.dockerContainerService = dockerContainerService;
        this.containerToImagesService = containerToImagesRepository;
        this.containerDomain = containerDomainV2;
        this.accountDTO = accountDTO;
        this.token = token;
        this.lastOperationService = lastOperationRepository;
        this.expire = expire;
        this.token1=token1;
        this.redisTemplate=redisTemplate;
    }


    @SneakyThrows
    @Override
    public void run() {
        ArrayList<RContainers> containerList = getContainerList(containerDomain.getCount());
        List<ContainerDomainV2> list = new ArrayList<>();
        for (RContainers r : containerList) {

            for (Container c : r.getContainers()) {
                ContainerDomainV2 containerDomainV2 = new ContainerDomainV2();
                containerDomainV2.setChapterId(containerDomain.getChapterId());
                containerDomainV2.setCourseId(containerDomain.getCourseId());
                containerDomainV2.setContainerIp(c.getLocal_ip());
                containerDomainV2.setContainerName(c.getName());
                containerDomainV2.setNewImageName(accountDTO.getUserName()+c.getName());
                list.add(containerDomainV2);
            }
        }
        Thread.sleep((expire-300L)*1000L);
        String s = redisTemplate.opsForValue().get(token1);
        if (s!=null) {
            List<ContainerToImages> containerToImagesList = saveContainerToImages(list);
            Integer num = dockerContainerService.getNum(containerDomain.getCourseId(), containerDomain.getChapterId(), accountDTO.getId());
            dockerContainerService.deleteContainerToImage(containerDomain.getCourseId(), containerDomain.getChapterId(), accountDTO.getId());
            containerToImagesService.save(containerToImagesList);
            List<LastOperation> lastOperations = new ArrayList<>();
            if (num == 0) {
                for (ContainerToImages c : containerToImagesList) {
                    LastOperation lastOperation = new LastOperation();
                    lastOperation.setUserId(accountDTO.getId());
                    lastOperation.setImagesVersion(c.getImageVersion());
                    lastOperation.setImagesName(c.getImagesName());
                    lastOperation.setId(UUID.randomUUID().toString());
                    lastOperation.setCourseId(c.getCourseId());
                    lastOperation.setCreateDate(new Date());
                    lastOperations.add(lastOperation);
                }
                lastOperationService.deleteByCourseIdAndUserId(containerDomain.getCourseId(), accountDTO.getId());
                lastOperationService.save(lastOperations);
            }

        }
    }

    public List<ContainerToImages> saveContainerToImages(List<ContainerDomainV2> list) {
        List<ContainerToImages> containerToImagesList = new ArrayList<>();
        for (ContainerDomainV2 domainV2 : list) {
            String save = dockerContainerService.save(domainV2, accountDTO, token);
            ContainerToImages containerToImages = new ContainerToImages();
            containerToImages.setId(UUID.randomUUID().toString());
            containerToImages.setCourseId(domainV2.getCourseId());
            containerToImages.setChapterId(domainV2.getChapterId());
            containerToImages.setUserId(accountDTO.getId());
            containerToImages.setContainerName(domainV2.getContainerName());
            containerToImages.setImagesName(domainV2.getNewImageName());
            containerToImages.setImageVersion(save);
            containerToImages.setCreateDate(new Date());
            containerToImages.setIsAuto(false);
            containerToImagesList.add(containerToImages);
        }
        return containerToImagesList;
    }

    public ArrayList<RContainers> getContainerList(Integer vmNum) throws InterruptedException {
        Thread.sleep(5L);
        FormData containerList = dockerContainerService.getContainerList(accountDTO.getUserName(), token);
        ArrayList<RContainers> rContainers = JSON.parseObject(containerList.getData().toString(), new TypeReference<ArrayList<RContainers>>() {
        });
        ArrayList<RContainers> newContainers = new ArrayList<>();
        int i = 0;
        if (rContainers.size()>0) {
            for (RContainers r : rContainers) {
                ArrayList<Container> newContainer = new ArrayList<>();
                if (r.getContainers()!=null && r.getContainers().size() > 0) {
                    for (Container c : r.getContainers()) {
                        if (i == 0) {
                            c.setName("master");
                            i++;
                        } else {
                            c.setName("slave" + i);
                            i++;
                        }
                        newContainer.add(c);
                    }
                }
                newContainers.add(r);
            }
        }
        if (vmNum == i) {
            return newContainers;
        } else {
            return getContainerList(vmNum);
        }
    }
}
